home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 11
/
CU Amiga Magazine's Super CD-ROM 11 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-06].iso
/
www
/
http
/
www.amigasupport.com
/
software
/
arc
/
bmpdt.lha
/
BMPdt
/
Source
/
ffr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-11
|
4KB
|
165 lines
#include <exec/memory.h>
#include <dos/dosextens.h>
#include <clib/macros.h>
#include <proto/exec.h>
struct FFRHandle {
struct StandardPacket fh_Pkt;
struct FileHandle *fh_Handle;
struct MsgPort fh_ReplyPort;
BYTE fh_Flag,pad;
UBYTE *fh_Buffer,
*fh_Pre,
*fh_Ptr;
ULONG fh_Left;
};
#define BUFFER_SIZE 32768L
#define FIRST_BLOCK 512L
#define mySetIoErr(fh,e) ((struct Process *)fh->fh_ReplyPort.mp_SigTask)->pr_Result2=(e)
#define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \
/*(l)->lh_Tail = NULL,*/ \
(l)->lh_TailPred = (struct Node *)&(l)->lh_Head)
VOID BeginRead(struct FFRHandle *fh,LONG bytes)
{
struct ExecBase *SysBase = *(struct ExecBase **)4L;
struct StandardPacket *sp;
fh->fh_Flag = -1; sp = &fh->fh_Pkt;
sp->sp_Msg.mn_Node.ln_Name = (char *)&sp->sp_Pkt;
sp->sp_Msg.mn_ReplyPort = &fh->fh_ReplyPort;
sp->sp_Msg.mn_Length = sizeof(struct StandardPacket);
sp->sp_Pkt.dp_Link = &sp->sp_Msg;
sp->sp_Pkt.dp_Port = &fh->fh_ReplyPort;
sp->sp_Pkt.dp_Type = ACTION_READ;
sp->sp_Pkt.dp_Arg1 = fh->fh_Handle->fh_Arg1;
sp->sp_Pkt.dp_Arg2 = (LONG)fh->fh_Pre;
sp->sp_Pkt.dp_Arg3 = bytes;
PutMsg(fh->fh_Handle->fh_Type,&sp->sp_Msg);
}
LONG EndRead(struct FFRHandle *fh)
{
struct ExecBase *SysBase = *(struct ExecBase **)4L;
struct StandardPacket *sp = &fh->fh_Pkt;
LONG res1;
(VOID) WaitPort(&fh->fh_ReplyPort);
(VOID) GetMsg(&fh->fh_ReplyPort);
fh->fh_Flag = FALSE;
if ((res1=sp->sp_Pkt.dp_Res1) < 0)
{ mySetIoErr(fh,sp->sp_Pkt.dp_Res2); return FALSE; }
fh->fh_Ptr = fh->fh_Pre;
fh->fh_Pre = fh->fh_Buffer;
fh->fh_Buffer = fh->fh_Ptr;
fh->fh_Left = res1;
if (res1 == sp->sp_Pkt.dp_Arg3)
BeginRead(fh,BUFFER_SIZE);
return TRUE;
}
LONG FFRGetC(struct FFRHandle *fh)
{
mySetIoErr(fh,0);
if (fh->fh_Left || (fh->fh_Flag && EndRead(fh) && fh->fh_Left))
{ fh->fh_Left--; return *fh->fh_Ptr++; };
return -1L;
}
LONG FFRRead(struct FFRHandle *fh,APTR buffer,LONG bytes)
{
struct ExecBase *SysBase = *(struct ExecBase **)4L;
UBYTE *ptr;
LONG left,size;
if (bytes <= fh->fh_Left)
{
CopyMem(fh->fh_Ptr,buffer,bytes);
fh->fh_Ptr += bytes; fh->fh_Left -= bytes;
return bytes;
}
left = bytes; ptr = buffer;
if (left > 0)
do {
size = MIN(fh->fh_Left,left);
if (size != 0)
{
CopyMem(fh->fh_Ptr,ptr,size);
fh->fh_Ptr += size; fh->fh_Left -= size;
ptr += size; left -= size;
}
if (left)
if (!fh->fh_Flag)
break;
else if (!EndRead(fh))
return -1L;
} while(left > 0);
return bytes-left;
}
VOID CloseFFR(struct FFRHandle *fh)
{
struct ExecBase *SysBase = *(struct ExecBase **)4L;
if (fh->fh_Flag != FALSE)
{ (VOID) WaitPort(&fh->fh_ReplyPort); (VOID) GetMsg(&fh->fh_ReplyPort); }
FreeVec(fh->fh_Pre);
FreeVec(fh->fh_Buffer);
FreeSignal(fh->fh_ReplyPort.mp_SigBit);
FreeVec(fh);
}
struct FFRHandle *OpenFFR(BPTR handle,LONG preRead)
{
if (handle != NULL)
{
struct ExecBase *SysBase = *(struct ExecBase **)4L;
struct FFRHandle *fh;
if ((fh=AllocVec(sizeof(struct FFRHandle),MEMF_PUBLIC|MEMF_CLEAR)) != NULL)
{
fh->fh_Handle = (struct FileHandle *)BADDR(handle);
fh->fh_ReplyPort.mp_Node.ln_Type = NT_MSGPORT;
if ((BYTE)(fh->fh_ReplyPort.mp_SigBit=AllocSignal(-1))>=0)
{
fh->fh_ReplyPort.mp_SigTask = FindTask(NULL);
NEWLIST(&fh->fh_ReplyPort.mp_MsgList);
if ((fh->fh_Buffer=AllocVec(BUFFER_SIZE,MEMF_PUBLIC)) != NULL)
{
if ((fh->fh_Pre=AllocVec(BUFFER_SIZE,MEMF_PUBLIC)) != NULL)
{
BeginRead(fh, FIRST_BLOCK-preRead); return fh;
}
FreeVec(fh->fh_Buffer);
}
FreeSignal(fh->fh_ReplyPort.mp_SigBit);
}
FreeVec(fh);
}
}
return NULL;
}